package com.flux.action


import android.support.v4.util.ArrayMap
import android.support.v4.util.Pair

import io.reactivex.disposables.Disposable


/**
 * Utility class to handle disposables
 */
object SubscriptionManager {
    private val mMap: ArrayMap<String, Pair<Int, Disposable>> = ArrayMap()

    /**
     * Given an action and a disposable, add the new disposable and dispose if there
     * was an existing one.
     */
    fun add(action: RxAction, disposable: Disposable) {
        val old = mMap.put(action.type, getPair(action, disposable))
        if (old != null && !old.second!!.isDisposed) old.second!!.dispose()
    }

    /**
     * Remove an rxAction and dispose from it
     */
    fun remove(action: RxAction) {
        val old = mMap.remove(action.type)
        if (old != null && !old.second!!.isDisposed) old.second!!.dispose()
    }

    /**
     * Checks if the action (with the same params) is already running a disposable
     *
     * @return true if the exact action is inside the map and running
     */
    operator fun contains(action: RxAction): Boolean {
        val old = mMap[action.type]
        return old != null && old.first == action.hashCode() && !old.second!!.isDisposed
    }

    /**
     * Clear all the disposables
     */
    @Synchronized
    fun clear() {
        if (mMap.isEmpty) return
        mMap.values.filterNot { it.second!!.isDisposed }.forEach { it.second!!.dispose() }
    }

    private fun getPair(action: RxAction, disposable: Disposable): Pair<Int, Disposable> {
        return Pair(action.hashCode(), disposable)
    }
}